home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
aminet
/
os20
/
cdity
/
mouseblanker121.lzh
/
MouseBlanker.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-07
|
54KB
|
1,633 lines
/*
* MouseBlanker.c
*
* Commodity
*
* Author: Stefan Sticht
*
* Copyright: source is public domain, no copyright
*
* Version history:
*
* V1.00 initial release
* V1.03 added window
* V1.04 recompiled with window.c V1.01
* V1.05 recompiled with window.c V1.02
* V1.06 recompiled with main.c V1.02
* V1.07 completly rewritten; shared commodity code thrown away; smaller, uses less CPU time
* V1.08 now uses Stricmp from utility.library
* V1.09 changed parameter parsing
* V1.10 changed parameter parsing; introduced an error with V1.09
* V1.11 a minor change
* V1.12 replaced menu by gadtools underscores & vanillakeys
* added blanking on key option
* disables inputevent-filters if not needed
* V1.13 added some LockIBase() where needed
* V1.14 recompiled with changed (for 68040 compatiblity) cback.o
* V1.15 major rework: changed mouse blanking method; added keypresses-feature
* many other changes
* V1.16 added a pointer to a chip-memory-region in simplesprite.posctldata for GetSprite()
* because it is not documented that GetSprite will handle a NULL in this field
* V1.17 small changes
* V1.18 removed enforcer hit under low mem in createallgadgets()
* now window opens on the front screen, if it is a public screen, else on
* the default public screen
* V1.19 14 Sep 1991 Stefan Sticht some small changes to reduce code size
* V1.20 16 Sep 1991 Stefan Sticht removed error in lockfrontpubscr()
* V1.21 Mon 07-Oct-91 Stefan Sticht removed obsolete code: replying IDCMP messages before CloseWindow()
*/
#define VERSION "V1.21"
/********************************************************************
* interfacing *
********************************************************************/
/*
* include files
*/
#include <math.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <devices/inputevent.h>
#include <exec/memory.h>
#include <intuition/intuitionbase.h>
#include <libraries/commodities.h>
#include <clib/alib_protos.h>
#include <clib/commodities_protos.h>
#include <pragmas/commodities_pragmas.h>
#include <clib/dos_protos.h>
#include <pragmas/dos_pragmas.h>
#include <clib/exec_protos.h>
#include <pragmas/exec_pragmas.h>
#include <clib/gadtools_protos.h>
#include <pragmas/gadtools_pragmas.h>
#include <clib/graphics_protos.h>
#include <pragmas/graphics_pragmas.h>
#include <clib/intuition_protos.h>
#include <pragmas/intuition_pragmas.h>
#include <clib/utility_protos.h>
#include <pragmas/utility_pragmas.h>
#ifdef DEBUG
#define printf KPrintF
#include <clib/dlib_protos.h>
#endif
/*
* prototypes
*/
long openwindow(void);
struct Gadget *createallgadgets(struct Gadget **glist, APTR vi, struct Screen *scr, ULONG *height, ULONG *width);
struct Library *myopenlibrary(char *name, unsigned long version);
struct Screen *lockfrontpubscr(void);
unsigned short command(unsigned short cmd);
void __saveds keymon(void);
void __saveds mousemon(void);
void __saveds timermon(void);
void blankmouse(short mode);
void closewindow(void);
void getkeypresses(void);
void getseconds(void);
void processmessages(short window);
void unblankmouse(void);
/*
* libraries opened by startup code; basepointers needed by function pragmas
*/
extern struct Library *DOSBase;
extern struct Library *SysBase;
/*
* Disable SAS/C CTRL/C handling
*/
void chkabort(void) {}
/********************************************************************
* global data *
********************************************************************/
/*
* definition of all messages
*/
#if defined(GERMAN)
#define RETRY_GADGETS "Wiederholen|Abbrechen"
#define RESUME_GADGETS "Weiter"
#define MSG_LIBRARY_OPENERR "Die %s (V%ld+) kann nicht geöffnet werden!"
#define MSG_WINDOW_OPENERR "Leider kann das Fenster nicht geöffnet werden!"
#define COM_NAME "Mausweg"
#define COM_DESCR "Versteckt Mauszeiger"
#define MSG_PROJECT "Projekt"
#define MSG_SECONDS "_Sekunden:"
#define MSG_SECONDS_SCC 'S'
#define MSG_KEY "_Tastendrücke:"
#define MSG_KEY_SCC 'T'
#define MSG_HIDE "_Verstecken"
#define MSG_HIDE_SCC 'V'
#define MSG_QUIT "_Beenden"
#define MSG_QUIT_SCC 'B'
#define YES "JA"
#define NO "NEIN"
#define TT_TIMEOUT "SEKUNDEN"
#define TT_KEY "TASTENDRUECKE"
#define TT_REBLANK "WIEDERHOLUNG"
/*
#elif defined(???) insert your language here!
*/
#else
#define RETRY_GADGETS "Retry|Cancel"
#define RESUME_GADGETS "Resume"
#define MSG_LIBRARY_OPENERR "%s (V%ld+) can't be opened!"
#define MSG_WINDOW_OPENERR "Window can't be opened!"
#define COM_NAME "MouseBlanker"
#define COM_DESCR "Blanks mouse pointer"
#define MSG_PROJECT "Project"
#define MSG_SECONDS "_Seconds:"
#define MSG_SECONDS_SCC 'S'
#define MSG_KEY "_Keypresses:"
#define MSG_KEY_SCC 'K'
#define MSG_HIDE "_Hide"
#define MSG_HIDE_SCC 'H'
#define MSG_QUIT "_Quit"
#define MSG_QUIT_SCC 'Q'
#define YES "YES"
#define NO "NO"
#define TT_TIMEOUT "SECONDS"
#define TT_KEY "KEYPRESSES"
#define TT_REBLANK "REBLANKTIMEOUT"
#endif
/*
* some constants
*/
#define COM_TITLE COM_NAME " " VERSION
#define CX_PRIORITY "CX_PRIORITY"
#define DEF_CX_PRIORITY 0
#define CX_POPKEY "CX_POPKEY"
#define DEF_CX_POPKEY ""
#define CX_POPUP "CX_POPUP"
#define DEF_CX_POPUP NO
#define DEF_TIMEOUT 3
#define DEF_KEY 5
#define DEF_REBLANK 2
/*
* with this ID we identify messages of our hotkey
*/
#define POP_KEY_ID 100
/*
* because there are several ways to initiate same functions
* every way initiates a command which is processed later
*/
#define CCMD_NOP 0
#define CCMD_QUIT 1
#define CCMD_SECONDS 2
#define CCMD_KEYPRESSES 3
#define CCMD_SECONDS_ACTIVATE 4
#define CCMD_KEYPRESSES_ACTIVATE 5
#define CCMD_OPENWINDOW 6
#define CCMD_CLOSEWINDOW 7
/*
* short-cuts by underscored gadgets shall be case-insensitive
*/
#define CASE_DIFF ('a' - 'A')
/*
* to make ActivateCxObj() more readable
*/
#define ON 1l
#define OFF 0l
/*
* data for SAS/C cback.o
*/
long _stack = 4096l;
char *_procname = COM_NAME;
long _priority = 0l;
long _BackGroundIO = 1;
extern BPTR _Backstdout;
/*
* library base pointers
*/
struct IntuitionBase *IntuitionBase;
struct Library *CxBase;
struct Library *IconBase;
struct Library *GadToolsBase;
struct Library *GfxBase;
struct Library *UtilityBase;
/*
* ponter to our task's Task structure
*/
struct Task *mytask;
/*
* signal we AllocSignal() in main()
*/
long signal = -1l;
/*
* pointer to timerequest
*/
struct timerequest *timereq;
short requestout = FALSE;
/*
* message ports
*/
struct MsgPort *idcmpport;
struct MsgPort *msgport;
/*
* signal flags
*/
unsigned long customsigflag;
unsigned long cxsigflag;
unsigned long idcmpsigflag;
/*
* programtitle and version for Version command
*/
char versionstring[] ="\0$VER: " COM_NAME " " VERSION;
/*
* helpstring
*/
#if defined(GERMAN)
char helpstring[] = "\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) von Stefan Sticht\n"\
"Aufruf: " COM_NAME " [" CX_PRIORITY "=<Zahl>] [" CX_POPKEY "=<Zeichenkette>] ["
CX_POPUP "=" YES "|" NO "] [" TT_TIMEOUT "=<Zahl>] ["\
TT_KEY "=<Zahl>] [" TT_REBLANK "=<Zahl>]\n";
/*
#elif defined(???)
*/
#else
char helpstring[] = "\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) by Stefan Sticht\n"
"Usage: " COM_NAME " [" CX_PRIORITY "=<number>] [" CX_POPKEY "=<string>] ["
CX_POPUP "=" YES "|" NO "] [" TT_TIMEOUT "=<number>] ["\
TT_KEY "=<number>] [" TT_REBLANK "=<number>]\n";
#endif
/*
* timeout values
*/
unsigned short timeout;
unsigned short timeoutseconds;
unsigned short timeoutperiod;
unsigned short keys;
unsigned short keypresses;
unsigned short reblank;
/*
* some constants for blanking the pointer
*/
#define NORMAL 0
#define FORCE 1
#define UNBLANKED 0
#define BLANKED 1
#define UNBLANK 0
#define BLANK 1
#define MOUSEBLANKED (blankstatus == BLANKED)
#define MOUSENOTBLANKED (blankstatus == UNBLANKED)
unsigned char blankstatus = UNBLANKED;
unsigned char blankrequest = UNBLANK;
struct SimpleSprite simplesprite = {
NULL, /* UWORD *posctldata; filled later */
0, /* UWORD height; */
0, 0, /* UWORD x,y; current position */
0 /* UWORD num; */
};
/*
* the tooltypearray
*/
char **tooltypes;
/*
* pointers to our commodities objects
*/
CxObj *broker = NULL;
CxObj *hotkeyfilter;
CxObj *mousefilter;
CxObj *timerfilter;
CxObj *keyfilter;
struct NewBroker newbroker = {
NB_VERSION, /* BYTE nb_Version */
COM_NAME, /* BYTE *nb_Name */
COM_TITLE, /* BYTE *nb_Title */
COM_DESCR, /* BYTE *nb_Descr */
NBU_NOTIFY | NBU_UNIQUE, /* SHORT nb_Unique */
COF_SHOW_HIDE, /* SHORT nb_Flags */
0, /* BYTE nb_Pri */
NULL, /* struct MsgPort nb_Port */
0 /* WORD nb_ReservedChannel */
};
/*
* some filters for filtering input events
*/
IX timerix = {
IX_VERSION, /* UBYTE ix_version */
IECLASS_TIMER, /* UBYTE ix_Class */
0, /* UWORD ix_Code */
0, /* UWORD ix_CodeMask */
0, /* UWORD ix_Qualifier */
0, /* UWORD ix_Qualmask */
0 /* UWORD ix_QualSame */
};
IX mouseix = {
IX_VERSION, /* UBYTE ix_version */
IECLASS_RAWMOUSE, /* UBYTE ix_Class */
0, /* UWORD ix_Code */
0, /* UWORD ix_CodeMask */
IEQUALIFIER_RELATIVEMOUSE, /* UWORD ix_Qualifier */
IEQUALIFIER_RELATIVEMOUSE, /* UWORD ix_Qualmask */
0 /* UWORD ix_QualSame */
};
/*
* we only want to know of key releases
*/
IX keyix = {
IX_VERSION, /* UBYTE ix_version */
IECLASS_RAWKEY, /* UBYTE ix_Class */
0, /* UWORD ix_Code */
IECODE_UP_PREFIX, /* UWORD ix_CodeMask */
0, /* UWORD ix_Qualifier */
IEQUALIFIER_REPEAT, /* UWORD ix_Qualmask */
0 /* UWORD ix_QualSame */
};
/*
* data for our window
*/
struct Window *win;
APTR vi;
struct Gadget *gadgetlist;
struct Screen *scr;
char windowtitle[] = COM_TITLE;
/*
* space for zoomed window pos & size
*/
WORD zoompos[4];
#define P_WA_Left 0
#define P_WA_Top 1
#define P_WA_Width 2
#define P_WA_Height 3
#define P_WA_Title 6
#define P_WA_PubScreen 7
#define P_WA_Gadgets 8
struct TagItem mywindowtag[] = {
WA_Left, 0l,
WA_Top, 20l,
WA_Width, 400l,
WA_Height, 150l,
WA_IDCMP, IDCMP_CLOSEWINDOW | BUTTONIDCMP | IDCMP_REFRESHWINDOW | IDCMP_VANILLAKEY,
WA_Flags, WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET | WFLG_SMART_REFRESH |
WFLG_ACTIVATE | WFLG_RMBTRAP,
WA_Title, (ULONG)windowtitle,
WA_PubScreen, 0l,
WA_Gadgets, 0l,
WA_Zoom, (ULONG)zoompos,
WA_AutoAdjust, FALSE,
TAG_END
};
char msg_seconds[] = MSG_SECONDS;
char msg_key[] = MSG_KEY;
char msg_hide[] = MSG_HIDE;
char msg_quit[] = MSG_QUIT;
/*
* gadget definitions
*/
#define DBL_INTERWIDTH (INTERWIDTH << 1)
#define DBL_INTERHEIGHT (INTERHEIGHT << 1)
#define GAD_SECONDS 6
#define GAD_KEY 7
#define GAD_HIDE 8
#define GAD_QUIT 9
struct Gadget *gad_seconds;
struct Gadget *gad_key;
/********************************************************************
* functions *
********************************************************************/
/*
* request(): a glue routine to EasyRequest as simple as printf plus
* titlestring, gadgettexts
*
* Input: char *title: pointer to the title of the requester
* char *gadgets: pointer to gadgettext
* char *text: text displayed in requester
*
* Result: same as EasyrequestArgs()
*
* !!! for more info see EasyRequestArgs() in Autodocs/intuition.doc !!!
*/
long request(char *title, char *gadgets, char *text, ...)
{
/*
* structure textreq only needed in this function, so hide it here
* must be static, in order to be initialized only once
*/
static struct EasyStruct textreq = {
sizeof (struct EasyStruct), /* ULONG es_StructSize */
0l, /* ULONG es_Flags */
NULL, /* UBYTE *es_Title */
NULL, /* UBYTE *es_TextFormat */
NULL, /* UBYTE *es_GadgetFormat */
};
va_list ap;
long rc;
/*
* get start of variable arguments
*/
va_start(ap, text);
/*
* update textreq
*/
textreq.es_Title = (UBYTE *)title;
textreq.es_TextFormat = (UBYTE *)text;
textreq.es_GadgetFormat = (UBYTE *)gadgets;
/*
* win may be NULL
*/
rc = EasyRequestArgs(win, &textreq, NULL, ap);
va_end(ap);
return(rc);
}
/*
* myopenlibrary(): same as OpenLibrary(), but opens a retry-requester
* if OpenLibrary() fails, to give the user a chance to
* copy the library to libs: and retry
* requires request(), see above
*/
struct Library *myopenlibrary(char *name, unsigned long version)
{
static char errortext[] = MSG_LIBRARY_OPENERR;
struct Library *libptr;
long ok = TRUE;
do {
if (!(libptr = OpenLibrary((UBYTE *)name, version))) {
if (IntuitionBase) ok = request(COM_NAME ":", RETRY_GADGETS, errortext, name, version);
else ok = FALSE;
}
} while (!libptr && ok);
return(libptr);
}
void main(int argc, char *argv[])
{
CxObj *customobj;
char *hotkey;
struct Message *msg;
long number;
short window = FALSE;
#ifdef DEBUG
printf("\n" COM_TITLE " started.\n");
#endif
if ((argc > 1) && (*argv[1] == '?')) {
/*
* display help string
*/
if (_Backstdout) {
Write(_Backstdout, helpstring, sizeof(helpstring) - 1l);
Close(_Backstdout);
}
return;
}
else if (argc && _Backstdout) Close(_Backstdout);
/*
* first we open intuition.library to be able to open an EasyRequest()
* Problem: how tell we the user that intuition.library didn't open?
* No intuition function will be available. I only tell him
* in the docs, because writing any code for calling once pre-V37
* AutoRequest() seems ridiculous, doesn't it?
*/
if (IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37l)) {
/*
* parse command line or tool types; we need icon.library therefore
*/
if (IconBase = myopenlibrary("icon.library", 37l)) {
/*
* create tooltypes array (requires open icon.library!!!)
*/
tooltypes = (char **)ArgArrayInit(argc, argv);
/*
* what priority wishes the user for the broker?
*/
newbroker.nb_Pri = ArgInt(tooltypes, CX_PRIORITY, DEF_CX_PRIORITY);
/*
* check for a hotkey
*/
hotkey = ArgString(tooltypes, CX_POPKEY, DEF_CX_POPKEY);
/*
* get the user's prefered timeout
*/
number = ArgInt(tooltypes, TT_TIMEOUT, DEF_TIMEOUT);
if (number < 1) timeoutseconds = 0;
else timeoutseconds = number;
timeoutperiod = timeoutseconds * 10;
/*
* how many keypresses needed to blank?
*/
number = ArgInt(tooltypes, TT_KEY, DEF_KEY);
if (number < 1) keypresses = 0;
else keypresses = number;
/*
* how many seconds to wait before reblanking?
*/
number = ArgInt(tooltypes, TT_REBLANK, DEF_REBLANK);
if (number < 1) reblank = 0;
else reblank = number;
/*
* now we need a function of utility.library
*/
if (UtilityBase = myopenlibrary("utility.library", 37l)) {
/*
* shall we open our window at startup?
*/
if (Stricmp(ArgString(tooltypes, CX_POPUP, DEF_CX_POPUP), YES) == 0l) window = TRUE;
/*
* we don not need it any longer, so we close it
*/
CloseLibrary(UtilityBase);
} /* if UtilityBase */
/*
* in this case it doesn't matter if we couldn't open utility.library; no error processing required
*
* now we need the commodities library (V37 of course, earlier versions may have problems)
*/
if (CxBase = myopenlibrary("commodities.library", 37l)) {
/*
* now let us open a message port for messages
*/
if (msgport = CreateMsgPort()) {
/*
* we have to copy the pointer to the port to newbroker
*/
newbroker.nb_Port = msgport;
cxsigflag = 1l << msgport->mp_SigBit;
/*
* before we do anything else we try to open the broker
* if it fails it is most likely that this commodity is already
* running and we don't start again; if so we avoid opening
* many resources, which must be closed although we do nothing
*/
if (broker = CxBroker(&newbroker, NULL)) {
/*
* we need some more libraries
*/
if (GfxBase = myopenlibrary("graphics.library", 37l)) {
if (GadToolsBase = myopenlibrary("gadtools.library", 37l)) {
/*
* now we create the three filter objects
*/
if (timerfilter = CxFilter(NULL)) {
SetFilterIX(timerfilter, &timerix);
AttachCxObj(broker, timerfilter);
if (mousefilter = CxFilter(NULL)) {
SetFilterIX(mousefilter, &mouseix);
AttachCxObj(broker, mousefilter);
if (keyfilter = CxFilter(NULL)) {
SetFilterIX(keyfilter, &keyix);
AttachCxObj(broker, keyfilter);
/*
* the custom object shall signal our task
* therefore we need a signal and a pointer to our task
*/
if ((signal = (long)AllocSignal(-1)) != -1) {
customsigflag = 1 << signal;
if (mytask = FindTask(NULL)) {
/*
* no we create the three custom objects
*/
if (customobj = CxCustom(timermon, 0l)) {
AttachCxObj(timerfilter, customobj);
if (customobj = CxCustom(mousemon, 0l)) {
AttachCxObj(mousefilter, customobj);
if (customobj = CxCustom(keymon, 0l)) {
AttachCxObj(keyfilter, customobj);
if (*hotkey && (hotkeyfilter = HotKey(hotkey, msgport, POP_KEY_ID))) {
AttachCxObj(broker, hotkeyfilter);
} /* if hotkey */
if (simplesprite.posctldata = AllocMem(8l, MEMF_CHIP|MEMF_CLEAR)) {
if (reblank) {
/*
* if we shall reblank we need the timer.device
*/
if (timereq = CreateIORequest(msgport, sizeof(struct timerequest))) {
if (OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)timereq, 0l)) {
/*
* timer.device didn't open
*/
DeleteIORequest(timereq);
timereq = NULL;
reblank = 0;
#ifdef DEBUG
printf("main(): OpenDevice(" TIMERNAME ") failed!\n");
#endif
}
}
else {
reblank = 0;
#ifdef DEBUG
printf("main(): CreateIORequest() failed!\n");
#endif
}
}
if (!CxObjError(timerfilter) &&
!CxObjError(mousefilter) &&
!CxObjError(keyfilter) &&
!(hotkeyfilter && CxObjError(hotkeyfilter))) {
/*
* deactivate timerfilter if timeoutseconds = 0
*/
if (!timeoutseconds) ActivateCxObj(timerfilter, OFF);
/*
* deactivate keyfilter if !keypresses
*/
if (!keypresses) ActivateCxObj(keyfilter, OFF);
/*
* activate our commodity
*/
ActivateCxObj(broker, ON);
/*
* deactivate again, if no timeoutseconds and not keypresses
*/
if (!timeoutseconds && !keypresses) ActivateCxObj(broker, OFF);
/*
* now watch our numerous ports
*/
processmessages(window);
} /* if !CxObjError() */
if (reblank && timereq) {
CloseDevice((struct IORequest *)timereq);
DeleteIORequest(timereq);
}
FreeMem(simplesprite.posctldata, 8l);
} /* if (simplesprite.posctldata = AllocMem(8l, MEMF_CHIP|MEMF_CLEAR) */
} /* if keymon */
} /* if mousemon */
} /* if timermon */
} /* if mytask */
FreeSignal(signal);
customsigflag = 0l;
} /* if signal */
} /* if keyfilter */
#ifdef DEBUG
else printf("main(): keyfilter = CxFilter() failed!\n");
#endif
} /* if mousefilter */
#ifdef DEBUG
else printf("main(): mousefilter = CxFilter() failed!\n");
#endif
} /* if timerfilter */
#ifdef DEBUG
else printf("main(): timerfilter = CxFilter() failed!\n");
#endif
CloseLibrary(GadToolsBase);
} /* if GadToolsBase */
CloseLibrary((struct Library *)GfxBase);
} /* if GfxBase */
DeleteCxObjAll(broker);
} /* if broker */
#ifdef DEBUG
else printf("main(): CxBroker() failed!\n");
#endif
/*
* delete our message port after replying all pending messages
*/
while (msg = GetMsg(msgport)) ReplyMsg(msg);
DeleteMsgPort(msgport);
#ifdef DEBUG
printf("main(): msgport deleted!\n");
#endif
} /* if msgport */
#ifdef DEBUG
else printf("main(): msgport = CraeteMsgPort() failed!\n");
#endif
CloseLibrary(CxBase);
} /* if CxBase */
/*
* free memory allocated by ArgArrayInit()
*/
ArgArrayDone();
CloseLibrary(IconBase);
} /* if IconBase */
CloseLibrary((struct Library *)IntuitionBase);
} /* if IntuitionBase */
} /* main() */
void processmessages(short window)
{
struct Message *msg;
unsigned long sigreceived;
unsigned long msgtype;
unsigned long msgid;
unsigned short quit = FALSE;
if (window) command(CCMD_OPENWINDOW);
while (!quit) {
sigreceived = Wait(SIGBREAKF_CTRL_C | cxsigflag | customsigflag | idcmpsigflag);
if (sigreceived & customsigflag) {
/*
* one of our custom commodities objects signalled us
*/
if (blankrequest == BLANK) blankmouse(NORMAL);
else unblankmouse();
}
if (sigreceived & cxsigflag) {
/*
* a message at our message-port
*/
while (msg = (struct Message *)GetMsg(msgport)) {
/*
* check if it is the reply from the timer.device
*/
if (msg == (struct Message *)timereq) {
/*
* the message from the timer.device tells us: reblank the mouse!
*/
#ifdef DEBUG
printf("processmessages(): timer told to reblank!\n");
#endif
blankmouse(FORCE);
}
else {
/*
* no reply from timer.device; we have to reply
*/
msgid = CxMsgID((CxMsg *)msg);
msgtype = CxMsgType((CxMsg *)msg);
ReplyMsg(msg);
switch (msgtype) {
case CXM_IEVENT:
if (msgid == POP_KEY_ID) command(CCMD_OPENWINDOW);
break;
case CXM_COMMAND:
switch (msgid) {
case CXCMD_KILL:
quit = command(CCMD_QUIT);
break;
case CXCMD_DISABLE:
ActivateCxObj(broker, OFF);
unblankmouse();
break;
case CXCMD_ENABLE:
ActivateCxObj(broker, ON);
break;
case CXCMD_UNIQUE:
case CXCMD_APPEAR:
command(CCMD_OPENWINDOW);
break;
case CXCMD_DISAPPEAR:
command(CCMD_CLOSEWINDOW);
break;
}
break;
} /* switch msgtype */
} /* if (msg != timerreq) */
} /* while CxMsg */
} /* if (sigreceived & cxsigflag) */
if (sigreceived & idcmpsigflag) {
APTR *object;
ULONG class;
UWORD code;
while (idcmpport && (msg = (struct Message *)GT_GetIMsg(idcmpport))) {
/*
* handle IDCMP messages
*/
class = ((struct IntuiMessage *)msg)->Class;
code = ((struct IntuiMessage *)msg)->Code;
object = ((struct IntuiMessage *)msg)->IAddress;
GT_ReplyIMsg((struct IntuiMessage *)msg);
switch (class) {
case CLOSEWINDOW:
command(CCMD_CLOSEWINDOW);
break;
case REFRESHWINDOW:
if (win) {
GT_BeginRefresh(win);
GT_EndRefresh(win, TRUE);
}
break;
case GADGETUP:
if (object) quit = command((unsigned short)((struct Gadget *)object)->UserData);
break;
case VANILLAKEY:
switch (code) {
case 27:
case MSG_HIDE_SCC:
case MSG_HIDE_SCC + CASE_DIFF:
command(CCMD_CLOSEWINDOW);
break;
case MSG_QUIT_SCC:
case MSG_QUIT_SCC + CASE_DIFF:
quit = command(CCMD_QUIT);
break;
case MSG_SECONDS_SCC:
case MSG_SECONDS_SCC + CASE_DIFF:
command(CCMD_SECONDS_ACTIVATE);
break;
case MSG_KEY_SCC:
case MSG_KEY_SCC + CASE_DIFF:
command(CCMD_KEYPRESSES_ACTIVATE);
break;
}
break;
} /* switch class */
} /* while idcmp message */
} /* if (sigreceived & idcmpsigflag) */
if (sigreceived & SIGBREAKF_CTRL_C) {
/*
* someone sent us a CTRL-C: we must go home now
*/
quit = command(CCMD_QUIT);
}
} /* while !quit */
/*
* we are going home; first we deactivate the broker, ...
*/
ActivateCxObj(broker, OFF);
#ifdef DEBUG
printf("processmessages(): leaving processmessages(), broker disabled\n");
#endif
/*
* ...then we close the window...
*/
closewindow();
unblankmouse();
}
unsigned short command(unsigned short cmd)
{
unsigned short quit = FALSE;
#ifdef DEBUG
printf("command(): command = %ld\n", cmd);
#endif
switch(cmd) {
case CCMD_NOP:
break;
case CCMD_QUIT:
quit = TRUE;
break;
case CCMD_SECONDS:
getseconds();
break;
case CCMD_SECONDS_ACTIVATE:
if (win) ActivateGadget(gad_seconds, win, NULL);
break;
case CCMD_KEYPRESSES:
getkeypresses();
break;
case CCMD_KEYPRESSES_ACTIVATE:
if (win) ActivateGadget(gad_key, win, NULL);
break;
case CCMD_OPENWINDOW:
if (!openwindow()) request(COM_NAME ":", RESUME_GADGETS, MSG_WINDOW_OPENERR);
break;
case CCMD_CLOSEWINDOW:
getseconds();
getkeypresses();
closewindow();
break;
} /* switch (command) */
return(quit);
}
/************************
* commodity functions *
************************/
void __saveds timermon(void)
{
if (++timeout >= timeoutperiod) {
blankrequest = BLANK;
if (mytask && customsigflag) Signal(mytask, customsigflag);
timeout = 0;
#ifdef DEBUG
printf(COM_NAME ": timermon blanked\n");
#endif
}
}
void __saveds mousemon(void)
{
timeout = 0;
keys = 0;
if (MOUSEBLANKED && blankrequest != UNBLANK) {
blankrequest = UNBLANK;
if (mytask && customsigflag) Signal(mytask, customsigflag);
#ifdef DEBUG
printf(COM_NAME ": mousemon unblanked\n");
#endif
}
}
void __saveds keymon(void)
{
if (++keys >= keypresses) {
if (MOUSENOTBLANKED) {
blankrequest = BLANK;
if (mytask && customsigflag) Signal(mytask, customsigflag);
#ifdef DEBUG
printf(COM_NAME ": keymon blanked\n");
#endif
}
}
}
/*********************
* window functions *
*********************/
struct Screen *lockfrontpubscr(void)
{
struct Screen *scr;
struct Screen *pubscr = NULL;
struct List *pslist;
struct PubScreenNode *psnode;
unsigned long lock;
unsigned short screentype;
lock = LockIBase(0l);
if (scr = IntuitionBase->FirstScreen) {
screentype = scr->Flags & SCREENTYPE;
UnlockIBase(lock);
if (screentype == PUBLICSCREEN || screentype == WBENCHSCREEN) {
if (pslist = LockPubScreenList()) {
for (psnode = (struct PubScreenNode *)pslist->lh_Head;
psnode->psn_Node.ln_Succ && (psnode->psn_Screen != scr);
psnode = (struct PubScreenNode *)psnode->psn_Node.ln_Succ);
if (psnode && (psnode->psn_Screen == scr) && !(psnode->psn_Flags & PSNF_PRIVATE)) {
pubscr = LockPubScreen(psnode->psn_Node.ln_Name);
}
UnlockPubScreenList();
}
}
}
else UnlockIBase(lock);
if (pubscr && ((pubscr->Width < 640) || (pubscr->Height < 200))) {
UnlockPubScreen(NULL, pubscr);
pubscr = NULL;
}
/*
* no locked screen yet, try default public screen
*/
if (!pubscr) pubscr = LockPubScreen(NULL);
return(pubscr);
}
long openwindow(void)
{
struct DimensionInfo di;
struct Rectangle *rect;
unsigned long vpmid;
long ok;
if (win) {
/*
* dont't open window but pop it to front, unzip it
*
* unzip window if zipped
*/
if (win->Height < mywindowtag[P_WA_Height].ti_Data) ZipWindow(win);
/*
* window to front
*/
WindowToFront(win);
/*
* activate window
*/
if (win != IntuitionBase->ActiveWindow) ActivateWindow(win);
/*
* screen to front
*/
if (win->WScreen != IntuitionBase->FirstScreen) ScreenToFront(win->WScreen);
ok = TRUE;
}
else {
/*
* lock the default public screen
*/
if (scr = lockfrontpubscr()) {
/*
* GetVisualInfo() for gadtools
*/
if (vi = GetVisualInfo(scr, TAG_DONE)) {
/*
* update some window information
*/
mywindowtag[P_WA_Width].ti_Data = zoompos[2] =
TextLength(&scr->RastPort, (STRPTR)windowtitle, sizeof(windowtitle) - 1l) + 100;
mywindowtag[P_WA_Height].ti_Data = zoompos[3] =
scr->WBorTop + scr->RastPort.TxHeight + 1;
/*
* create all gadgets:
*
* this function may also change the width and height of our window
*/
if (createallgadgets(&gadgetlist, vi, scr,
&mywindowtag[P_WA_Height].ti_Data,
&mywindowtag[P_WA_Width].ti_Data)) {
/*
* center the window in the visible box of the screen
*/
if ((vpmid = GetVPModeID(&scr->ViewPort )) != INVALID_ID) {
GetDisplayInfoData(0, (UBYTE *)&di, sizeof(struct DimensionInfo), DTAG_DIMS, vpmid);
rect = &di.TxtOScan;
zoompos[0] = mywindowtag[P_WA_Left].ti_Data =
(scr->LeftEdge < 0 ? -scr->LeftEdge : 0) +
((min((rect->MaxX - rect->MinX + 1), scr->Width) -
mywindowtag[P_WA_Width].ti_Data) >> 1);
zoompos[1] = mywindowtag[P_WA_Top].ti_Data =
(scr->TopEdge < 0 ? -scr->TopEdge : 0) +
((min((rect->MaxY - rect->MinY + 1), scr->Height) -
mywindowtag[P_WA_Height].ti_Data) >> 1);
}
mywindowtag[P_WA_PubScreen].ti_Data = (ULONG)scr;
mywindowtag[P_WA_Gadgets].ti_Data = (ULONG)gadgetlist;
if (win = OpenWindowTagList(NULL, mywindowtag)) {
/*
* save IDCMP port
*/
idcmpport = win->UserPort;
idcmpsigflag = 1L << idcmpport->mp_SigBit;
GT_RefreshWindow(win, NULL);
/*
* switch screen to front
*/
if (win->WScreen != IntuitionBase->FirstScreen) ScreenToFront(win->WScreen);
ok = TRUE;
} /* if (win = OpenWindowTagList(NULL, mywindowtag)) */
#ifdef DEBUG
else printf("openwindow(): OpenWindowTagList() failed!\n");
#endif
} /* if (createallgadgets() */
#ifdef DEBUG
else printf("openwindow(): createallgadgets() failed!\n");
#endif
} /* if (vi = GetVisualInfo(scr, TAG_DONE)) */
#ifdef DEBUG
else printf("openwindow(): GetVisualInfo() failed!\n");
#endif
} /* if (scr = LockPubScreen(NULL)) */
#ifdef DEBUG
else printf("openwindow(): LockPubScr() failed!\n");
#endif
if (!ok) {
/*
* window could not be opened - free all resources
*/
closewindow();
}
} /* if (!win) */
return(ok);
}
void closewindow(void)
{
if (win) {
/*
* now close the window
*/
CloseWindow(win);
win = NULL;
idcmpport = NULL;
idcmpsigflag = 0l;
}
if (gadgetlist) {
FreeGadgets(gadgetlist);
gadgetlist = NULL;
}
if (vi) {
FreeVisualInfo(vi);
vi = NULL;
}
if (scr) {
UnlockPubScreen(NULL, scr);
scr = NULL;
}
}
void getseconds(void)
{
long number;
if (win) {
if ((number = ((struct StringInfo *)gad_seconds->SpecialInfo)->LongInt) > 0) {
/*
* input value ok
*/
timeoutseconds = number;
timeoutperiod = timeoutseconds * 10;
timeout = 0;
if (MOUSENOTBLANKED) {
/*
* activate timerfilter if mouse isn't blanked
*/
ActivateCxObj(timerfilter, ON);
#ifdef DEBUG
printf("getseconds(): timerfilter enabled\n");
#endif
}
}
else {
/*
* value given was < 1
*/
timeoutseconds = timeout = 0;
/*
* disable timerfilter
*/
ActivateCxObj(timerfilter, OFF);
#ifdef DEBUG
printf("getseconds(): timerfilter disabled\n");
#endif
/*
* update gadget contents
*/
GT_SetGadgetAttrs(gad_seconds, win, NULL, GTIN_Number, timeoutseconds, TAG_END);
}
} /* if win */
}
void getkeypresses(void)
{
long number;
if (win) {
if ((number = ((struct StringInfo *)gad_key->SpecialInfo)->LongInt) > 0) {
/*
* input value ok
*/
keypresses = number;
keys = 0;
if (MOUSENOTBLANKED) {
/*
* activate keyfilter if mouse isn't blanked
*/
ActivateCxObj(keyfilter, ON);
#ifdef DEBUG
printf("getkeypresses(): keyfilter enabled\n");
#endif
}
}
else {
/*
* value given was < 1
*/
keypresses = 0;
/*
* disable timerfilter
*/
ActivateCxObj(keyfilter, OFF);
#ifdef DEBUG
printf("getkeypresses(): keyfilter disabled\n");
#endif
/*
* update gadget contents
*/
GT_SetGadgetAttrs(gad_key, win, NULL, GTIN_Number, keypresses, TAG_END);
}
} /* if win */
}
/*
* createallgadgets(): create all gadgets and put required width and height
* of window in height and width
*/
struct Gadget *createallgadgets(struct Gadget **glist, APTR vi, struct Screen *scr, ULONG *height, ULONG *width)
{
static struct NewGadget ng;
struct Gadget *gad;
struct RastPort *rp;
short buttonwidth;
short gadtitlewidth;
short stringgadgetwidth;
short dummy;
/*
* first get RastPort of screen to determine some TextLength()
*/
rp = &scr->RastPort;
/*
* maximum width of a button
*/
buttonwidth = TextLength(rp, (STRPTR)&msg_hide[1], sizeof(msg_hide) - 2l);
dummy = TextLength(rp, (STRPTR)&msg_quit[1], sizeof(msg_quit) - 2l);
buttonwidth = max(buttonwidth, dummy);
buttonwidth += DBL_INTERWIDTH;
/*
* check out if the window's width has to be enlarged
*/
*width = max((buttonwidth << 1) + (DBL_INTERWIDTH + INTERWIDTH), *width);
/*
* now the maximum length of the text left to the stringgadgets
*/
gadtitlewidth = TextLength(rp, (STRPTR)&msg_seconds[1], sizeof(msg_seconds) - 2l);
dummy = TextLength(rp, (STRPTR)&msg_key[1], sizeof(msg_key) - 2l);
gadtitlewidth = max(gadtitlewidth, dummy);
/*
* calculate width of a stringgadet: I tried out that 6 times the width
* of the digit "0" gives a nice value for the integer gadget
*/
stringgadgetwidth = TextLength(rp, (STRPTR)"000000", 6l);
/*
* check out if the window's width has to be enlarged
*/
*width = max(stringgadgetwidth + gadtitlewidth + DBL_INTERWIDTH + INTERWIDTH, *width);
/*
* now create the gadgets
*/
gad = CreateContext(glist);
/*
* seconds gadget
*/
ng.ng_TopEdge = scr->WBorTop + rp->TxHeight + 1 + INTERHEIGHT;
ng.ng_Width = stringgadgetwidth;
ng.ng_LeftEdge = ((*width - gadtitlewidth - stringgadgetwidth - INTERWIDTH) >> 1) +
gadtitlewidth + INTERWIDTH;
ng.ng_Height = rp->TxHeight + 4;
ng.ng_GadgetText = (UBYTE *)msg_seconds;
ng.ng_TextAttr = scr->Font;
ng.ng_GadgetID = GAD_SECONDS;
ng.ng_Flags = PLACETEXT_LEFT;
ng.ng_VisualInfo = vi;
ng.ng_UserData = (APTR)CCMD_SECONDS;
gad_seconds = gad = CreateGadget(INTEGER_KIND, gad, &ng,
GTIN_MaxChars, 3l,
GTIN_Number, (ULONG)timeoutseconds,
GT_Underscore, '_',
TAG_DONE);
/*
* key presses gadget
*/
ng.ng_TopEdge += ng.ng_Height + INTERHEIGHT;
ng.ng_GadgetText = (UBYTE *)msg_key;
ng.ng_GadgetID = GAD_KEY;
ng.ng_UserData = (APTR)CCMD_KEYPRESSES;
gad_key = gad = CreateGadget(INTEGER_KIND, gad, &ng,
GTIN_MaxChars, 3l,
GTIN_Number, (ULONG)keypresses,
GT_Underscore, '_',
TAG_DONE);
/*
* dummy now gets the spacing between the button gadgets
*/
dummy = (*width - (buttonwidth << 1)) / 3;
/*
* Hide gadget
*/
ng.ng_TopEdge += ng.ng_Height + INTERHEIGHT;
ng.ng_Width = buttonwidth;
ng.ng_LeftEdge = dummy;
ng.ng_GadgetText = (UBYTE *)msg_hide;
ng.ng_GadgetID = GAD_HIDE;
ng.ng_Flags = 0l;
ng.ng_UserData = (APTR)CCMD_CLOSEWINDOW;
gad = CreateGadget(BUTTON_KIND, gad, &ng, GT_Underscore, '_', TAG_DONE);
/*
* Quit gadget
*/
ng.ng_LeftEdge += ng.ng_Width + dummy;
ng.ng_GadgetText = (UBYTE *)msg_quit;
ng.ng_GadgetID = GAD_QUIT;
ng.ng_UserData = (APTR)CCMD_QUIT;
gad = CreateGadget(BUTTON_KIND, gad, &ng, GT_Underscore, '_', TAG_DONE);
*height = ng.ng_TopEdge + ng.ng_Height + scr->WBorBottom + INTERHEIGHT;
return(gad);
}
/****************************
* the mouse blanking part *
****************************/
/*
* blank mouse if not already blanked or if mode == FORCE
*/
void blankmouse(short mode)
{
#ifdef DEBUG
short ok;
#endif
if (MOUSENOTBLANKED || mode == FORCE) {
#ifdef DEBUG
printf("blankmouse(): *** blanking mouse ***\n");
#endif
/*
* mouse blanking is done by freeing sprite #0
*/
Forbid();
FreeSprite(0);
#ifdef DEBUG
ok = GetSprite(&simplesprite, 0);
#else
GetSprite(&simplesprite, 0);
#endif
Permit();
blankstatus = BLANKED;
#ifdef DEBUG
if (ok == -1) printf("blankmouse(): *** GetSprite failed ***\n");
#endif
if (mode != FORCE) {
/*
* we require the mousefilter, activate it
*/
ActivateCxObj(mousefilter, ON);
#ifdef DEBUG
printf("blankmouse(): mousefilter enabled\n");
#endif
/*
* timerfilter & keyfilter are obsolete
*/
ActivateCxObj(timerfilter, OFF);
ActivateCxObj(keyfilter, OFF);
#ifdef DEBUG
printf("blankmouse(): timerfilter & keyfilter disabled\n");
#endif
}
/*
* start a new timerrequest
*/
if (reblank && (mode == FORCE || !requestout)) {
timereq->tr_node.io_Command = TR_ADDREQUEST;
timereq->tr_time.tv_secs = reblank;
timereq->tr_time.tv_micro = 0l;
SendIO((struct IORequest *)timereq);
requestout = TRUE;
#ifdef DEBUG
printf("blankmouse(): timerequest sent out!\n");
#endif
}
}
}
/*
* unblank mouse if blanked
*/
void unblankmouse(void)
{
blankstatus = UNBLANKED;
if (timeoutseconds) {
/*
* we have to activate the timerfilter
*/
timeout = 0;
ActivateCxObj(timerfilter, ON);
#ifdef DEBUG
printf("unblankmouse(): timerfilter enabled\n");
#endif
}
else {
/*
* mousefilter filter is obsolete, disable it
*/
ActivateCxObj(mousefilter, OFF);
#ifdef DEBUG
printf("unblankmouse(): mousefilter disabled\n");
#endif
}
if (keypresses) {
/*
* we have to activate the keyfilter
*/
keys = 0;
ActivateCxObj(keyfilter, ON);
#ifdef DEBUG
printf("unblankmouse(): keyfilter enabled\n");
#endif
}
/*
* abort the timerrequest if it is not home yet
*/
if (requestout) {
AbortIO((struct IORequest *)timereq);
WaitIO((struct IORequest *)timereq);
requestout = FALSE;
#ifdef DEBUG
printf("unblankmouse(): timereq aborted!\n");
#endif
}
}